package me.leiusual.sharing.ui.account

import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import dagger.android.support.DaggerFragment
import kotlinx.android.synthetic.main.fragment_account_register.*
import me.leiusual.sharing.R
import me.leiusual.sharing.api.model.Register
import me.leiusual.sharing.api.model.RegisterByQRCode
import me.leiusual.sharing.repository.model.Data
import me.leiusual.sharing.ui.ScanActivity
import me.leiusual.sharing.ui.helper.HandleObserver
import me.leiusual.sharing.util.extension.toast
import timber.log.Timber
import javax.inject.Inject

/**
 * Create by leiusual on 2018/7/16
 */
class AccountRegisterFragment : DaggerFragment() {

  companion object {
    private const val REQ_SCAN_FOR_FULL = 1
    private const val REQ_SCAN_FOR_REGISTER = 2
  }

  @Inject
  lateinit var factory: ViewModelProvider.Factory

  private val viewModel: AccountRegisterViewModel by viewModels { factory }

  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    return inflater.inflate(R.layout.fragment_account_register, container, false)
  }

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    toolbar.setNavigationOnClickListener {
      findNavController().popBackStack()
    }

    // 判断有没有内置邀请人
    val defaultInvitor = try {
      val context = requireContext()
      val info = context.packageManager.getApplicationInfo(context.packageName, PackageManager.GET_META_DATA)
      info.metaData.getString("inviteCode")
    } catch (e: Exception) {
      Timber.w(e)
      null
    }
    if (!defaultInvitor.isNullOrBlank()) {
      // 自动填入
      edit_text_invite.setText(defaultInvitor)
      edit_text_invite.isEnabled = false

      // 禁用扫码填入
      text_view_scan_qr_code.isEnabled = false
    }

    text_view_send_sms.setOnClickListener {
      val phone = edit_text_phone.text.toString()
      viewModel.sendSMS(phone)
    }

    text_view_scan_qr_code.setOnClickListener {
      startActivityForResult(ScanActivity.intent(it.context), REQ_SCAN_FOR_FULL)
    }

    button_register.setOnClickListener {
      val mobile = edit_text_phone.text.toString()
      val checkCode = edit_text_code.text.toString()
      val inviteCode = edit_text_invite.text.toString()
      viewModel.register(mobile, checkCode, inviteCode)
    }

    text_view_scan_register.setOnClickListener {
      startActivityForResult(ScanActivity.intent(it.context), REQ_SCAN_FOR_REGISTER)
    }

    text_view_agreement.setOnClickListener {
      findNavController().navigate(R.id.action_accountRegisterFragment_to_accountAgreementFragment)
    }

    observeData()
  }

  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    Timber.v("onActivityResult %s, %s, %s", requestCode, resultCode, data)

    if (requestCode == REQ_SCAN_FOR_FULL && resultCode == Activity.RESULT_OK) {
      val text = ScanActivity.getResult(data) ?: return
      val inviteCode = try {
        Uri.parse(text).getQueryParameter("ic")
      } catch (e: Throwable) {
        Timber.w(e)
        null
      }
      edit_text_invite.setText(inviteCode)
    }

    if (requestCode == REQ_SCAN_FOR_REGISTER && resultCode == Activity.RESULT_OK) {
      val text = ScanActivity.getResult(data) ?: return
      try {
        val uri = Uri.parse(text)
        val encodedClientId = uri.getQueryParameter("client_id") ?: return
        val inviteCode = uri.getQueryParameter("ic") ?: return
        viewModel.registerByQRCode(encodedClientId, inviteCode)
      } catch (e: Throwable) {
        Timber.w(e)
      }
    }
  }

  private fun observeData() {
    viewModel.sendSMS.observe(viewLifecycleOwner, HandleObserver {
      Timber.v("sendSMS = %s", it)
      when (it) {
        is Data.Loading -> {
          text_view_send_sms.isEnabled = false
        }
        is Data.Error -> {
          text_view_send_sms.isEnabled = true
          toast(it.error.message)
        }
        is Data.Success -> {
          text_view_send_sms.startTimber()
          toast("短信发送成功")
        }
      }
    })

    viewModel.register.observe(viewLifecycleOwner, HandleObserver {
      Timber.v("register = %s", it)
      when (it) {
        is Data.Loading -> {
          button_register.isEnabled = false
        }
        is Data.Error -> {
          button_register.isEnabled = true
          toast(it.error.message)
        }
        is Data.Success -> {
          toast("注册成功")
          showRegisterResult(it.data)
        }
      }
    })

    viewModel.registerByQRCode.observe(viewLifecycleOwner, HandleObserver {
      Timber.v("registerByQRCode = %s", it)
      when (it) {
        is Data.Loading -> {
          toast("注册用户中，请稍等...")
        }
        is Data.Error -> {
          toast(it.error.message)
        }
        is Data.Success -> {
          showRegisterResult(it.data)
        }
      }
    })
  }

  private fun showRegisterResult(data: Register.Response) {
    AlertDialog.Builder(requireContext())
        .setMessage("登录帐号：${data.username}\n登录密码：${data.originPassword}")
        .setPositiveButton("确认") { _, _ -> findNavController().popBackStack() }
        .setCancelable(false)
        .show()
  }

  private fun showRegisterResult(data: RegisterByQRCode.Response) {
    val message = if (data.invitor == null) {
      "登录帐号：${data.username}\n登录密码：${data.originPassword}"
    } else {
      "邀请人：${data.invitor}\n登录帐号：${data.username}\n登录密码：${data.originPassword}"
    }
    AlertDialog.Builder(requireContext())
        .setMessage(message)
        .setPositiveButton("确认") { _, _ -> findNavController().popBackStack() }
        .setCancelable(false)
        .show()
  }
}
